#ifndef BOOSTCONTROL_H
#define BOOSTCONTROL_H

#include <QObject>
#include "SerialBase.h"
#include <queue>
#include <mutex>
#include <condition_variable>
#include <chrono>
#include <thread>
#include "src/define/data_define.h"
#include <boost/asio/serial_port.hpp>
#include <boost/asio.hpp>
#include <boost/timer.hpp>
#include "boost/circular_buffer.hpp"
#include <boost/thread.hpp>
#include <boost/algorithm/hex.hpp>

typedef boost::circular_buffer<unsigned char> CCircularBuffer;
using namespace std ;
using namespace boost::asio;

#define USE_ASYNC 1

struct CircleBuff
{
    queue<UC> buff;
    std::string  okData;
    bool crcCheck = false;
    void operator <(UC d){
        buff.push(d);
        buff.pop();
    }
    void operator <<(UC d){
        buff.push(d);
    }
    queue<UC> operator ->(){
        return buff;
    }
    bool getHeader(){
        return     (UC)buff.front() == (UC)0xff;
    }

    bool CRC(){
        queue<UC> temp = buff;
        string buffS ;
        for(int i=0;i < 21;i++){
            buffS.push_back(temp.front());
            temp.pop();
        }
        UC2 crc = 0x0000;
        for(int i=1;i < 21 - 1;i++){
            crc += (UC)buffS[i] ;
        }
        crc &=  0xFF;
        if(crc - (UC)buffS[21-1]){
            return false;
        }
        okData =  buffS;
        crcCheck = true;
        return true;
    }
};

// 毫秒
typedef std::chrono::time_point<std::chrono::steady_clock, std::chrono::duration<double, std::ratio<1, 1000>>> Millsecond ;

class BoostControl:public SerialBase
{
public:
    explicit BoostControl();
    void InitDevice();

    virtual QStringList ScanSerial() override;
    ///
    virtual std::string SendUntilRec(const char *sendBuf,int msecs = 3000) override;
    ///
    virtual bool GetOpened() override;
    ///
    virtual void CloseSerial() override;
    ///
    virtual void SendBuff(const char* sendBuf) override;

    virtual void OpenPort(const char* port,int bau) override;//Open

    virtual bool ReadBuff() override;

    string currentBuff;

private:
    /// 通信管理
    std::shared_ptr<boost::asio::serial_port> _serialPort_ptr ;
    /// 线程同步锁
    std::recursive_mutex _mtx ;
    /// 条件变量
    std::condition_variable _condReply ;
    /// 条件变量锁
    std::mutex _mtxReply ;
    /// 是否已经应答
    bool _bReply ;
    /// asio 服务管理
    boost::asio::io_service _service ;
    ///
    std::thread _thService ;
    /// 存放应答指令
    unsigned char _readBuffer[21] ;
    unsigned char recvData[1];

    CircleBuff cir_buff;
    void preConnectDevice();
    void recvReply(const boost::system::error_code &ec, size_t);
    void recvReplyInterrupt(const boost::system::error_code &ec, size_t);
    void waitReply();
};

#endif // BOOSTCONTROL_H
